package com.digital.welcome.util;

import com.google.common.io.BaseEncoding;
import io.jsonwebtoken.*;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * @PackageName:com.example.welcome.util
 * @ClassName:JwtUtil
 * @Description:Jwt工具类，生成JWT和认证
 */
public class JwtUtil {

    /**
     * 由字符串生成加密key
     *
     * @return SecretKey
     */
    public static SecretKey generalKey() {
        String stringKey = "1sf12sds21ie1inecs078j";//salt
        byte[] encodedKey = BaseEncoding.base64().decode(stringKey);// 本地的密码解码
//        System.out.println(Arrays.toString(encodedKey));
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "HmacSHA256");// 根据给定的字节数组使用加密算法构造一个密钥
        return key;
    }

    /**
     * 加密
     *
     * @param userNameId
     * @param issuer
     * @param subject
     * @param ttlMillis
     * @return
     */
    public static String createJWT(String userNameId, String issuer, String subject, long ttlMillis) {

        //The JWT signature algorithm we will be using to sign the token
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //We will sign our JWT with our ApiKey secret
        SecretKey signingKey = generalKey();

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder()
                .setId(userNameId)
                .setIssuedAt(now)//签发时间
                .setSubject(subject)
                .setIssuer(issuer)
                .signWith(signatureAlgorithm, signingKey);

        //if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);//设置过期时间
        }

        //Builds the JWT and serializes it to a compact, URL-safe string
        return builder.compact();
    }

    /**
     * 解密
     *
     * @param jwt
     */
    public static Claims parseJWT(String jwt) {
        //This line will throw an exception if
        // it is not a signed JWS (as expected)
        try {
            SecretKey secretKey = generalKey();
            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(jwt)
                    .getBody();
            return claims;
        }catch (ExpiredJwtException e){
            return null;
        }
//        System.out.println("ID: " + claims.getId());
//        System.out.println("Subject: " + claims.getSubject());
//        System.out.println("Issuer: " + claims.getIssuer());
//        System.out.println("Expiration: " + claims.getExpiration());

    }

    public static boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }

    public static void main(String[] args) {

        //加密
        String jwt = createJWT("13dsdda", "zhangsan", "1", 1000 * 60 * 60 * 24 * 7);
        System.out.println(jwt);

        //解密
        Claims claims=parseJWT(jwt);
        System.out.println(claims);
    }
}
